#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <pcap/pcap.h>
#include <sys/types.h>
#include <pthread.h>

void * recv_data_pthread_handler (void *);

void deal_packet_data(u_char * userarg, const struct pcap_pkthdr *,const u_char * packet);


int main(int argc, char const *argv[])
{
     // 1. 创建pcap文件句柄
    pcap_t* p_capId = pcap_open_live("ens33" , 1500 , 0, 0 ,NULL );

    pcap_t* p_capId2 = pcap_open_live("ens38" , 1500 , 0, 0 ,NULL );


    if(p_capId == NULL)
    {
        perror("fail to pcap_open_live");
        return 0;
    }

     // 2. 设置过滤规则
    char buf[] = "ip dst host 192.168.121.121";
    struct bpf_program program;

    if(pcap_compile(p_capId , &program , buf, 0, 0xffffff00) == 0 )
    {
        // 设置过滤规则
        pcap_setfilter(p_capId, &program);
    }


    // 创建线程来处理发过来的ping命令 （icmp报文）
    pthread_t handler_pkt_pid;
    pthread_create(&handler_pkt_pid , NULL, recv_data_pthread_handler , (void *)p_capId );
    pthread_detach(handler_pkt_pid);


    // pthread_t handler_pkt_pid;
    // pthread_create(&handler_pkt_pid , NULL, recv_data_pthread_handler , (void *)p_capId );
    // pthread_detach(handler_pkt_pid);


    while (1)
    {

    }

    pcap_close(p_capId);
    pcap_close(p_capId2);

    
    return 0;
}


/****************
 * 捕获数据线程的处理方法
 * 
 * 
 * ************/

void * recv_data_pthread_handler (void * arg)
{
    
    pcap_t* p_capId = (pcap_t*)arg;
    pcap_loop(p_capId, -1 , deal_packet_data, NULL);   // 带阻塞的

}



void deal_packet_data(u_char * userarg , const struct pcap_pkthdr * pkthdr,const u_char * packet)
{
    printf("帧数的实际长度:%u\n",pkthdr->caplen);
    uint32_t cap_data_len = pkthdr->caplen;

    struct ether_header * eth_hdr = (struct ether_header *)packet;
    printf("src mac-->%02x:%02x:%02x:%02x:%02x:%02x\n", 
    eth_hdr->ether_shost[0], eth_hdr->ether_shost[1],eth_hdr->ether_shost[2],
    eth_hdr->ether_shost[3], eth_hdr->ether_shost[4],eth_hdr->ether_shost[5]);

    printf("dst mac-->%02x:%02x:%02x:%02x:%02x:%02x\n", 
    eth_hdr->ether_dhost[0], eth_hdr->ether_dhost[1],eth_hdr->ether_dhost[2],
    eth_hdr->ether_dhost[3], eth_hdr->ether_dhost[4],eth_hdr->ether_dhost[5]);

    // char src_mac[18] = "";
    // char dst_mac[18] = "";
    // sprintf(dst_mac, "%02x:%02x:%02x:%02x:%02x:%02x",
    // packet[0], packet[1], packet[2], packet[3], packet[4], packet[5]);

    // sprintf(src_mac, "%02x:%02x:%02x:%02x:%02x:%02x",
    // packet[0 + 6], packet[1 + 6], packet[2 + 6], packet[3 + 6], packet[4 + 6],
    // packet[5 + 6]);
    // printf("mac:%s-->%s\n", src_mac, dst_mac);


    // 获取目的ip，判断和自身的ip是否在同一个网段
    struct iphdr * iphdr = (struct iphdr *)(packet + 14);

    char  src_ip[20] = "";
     
    memcpy(src_ip ,inet_ntoa( ((struct sockaddr_in *)(&iphdr->saddr) )->sin_addr ), 20 );
    // inet_ntoa( ((struct sockaddr_in *)(&iphdr->saddr) )->sin_addr  );
    printf("src_ip:%s\n",src_ip);
    // iphdr->

}